<!--
Copyright © 2017, Che-Wei Hsu <cwxhsu@gmail.com>
This file is part of the MintCM.
Some rights reserved. See README.
-->

<html>

<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../css/mcm_style.css">
</head>

<body class="css_body">

<div class="css_div_box_frame_full">
  <div class="css_div_box_title">chapter 05-02</div>
  <div class="css_div_box_content">
  </div>
</div>
<br>

<div class="css_div_box_frame_full">
  <div class="css_div_box_title">使用方式 (用戶端)</div>
  <div class="css_div_box_content">
    <br>

    此章節說明如何在用戶端程式使用 <a href="mcm_0302.html#hook_0302_mcm_lulib_run_01">mcm_lulib_run</a>
    傳遞資料給內部模組以及從內部模組回傳資料.
    <br><br>

  </div>
</div>
<br>

<div class="css_div_box_frame_full">
  <div class="css_div_box_title">範例程式</div>
  <div class="css_div_box_content">
    <br>

<pre class="css_pre_code">
外部程式部分

#include &lt;time.h&gt;
#include &lt;errno.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;
    char req_data1[128], *rep_data1;
    MCM_DTYPE_USIZE_TD req_len1, rep_len1;
    int req_data2[4], *rep_data2;
    MCM_DTYPE_USIZE_TD req_len2, rep_len2, idx, count;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RO;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 測試-01 : 字串類型資料.

    path1 = "mcm_module_user_data_test_01";
    DMSG("[run] %s", path1);

    snprintf(req_data1, sizeof(req_data1), "user-data-%u", rand());
    req_len1 = strlen(req_data1) + 1;
    DMSG("send [" MCM_DTYPE_USIZE_PF "][%s]", req_len1, req_data1);

    if(mcm_lulib_run(&self_lulib, path1, &req_data1, req_len1, (void **) &rep_data1, &rep_len1)
                     < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

    DMSG("recv [" MCM_DTYPE_USIZE_PF "][%s]", rep_len1, rep_data1);
    free(rep_data1);

    // 測試-02 : 字節類型資料.

    path1 = "mcm_module_user_data_test_02";
    DMSG("[run] %s", path1);

    count = sizeof(req_data2) / sizeof(int);
    for(idx = 0; idx < count; idx++)
        req_data2[idx] = rand() % 100;

    req_len2 = sizeof(req_data2);

    DMSG("send [" MCM_DTYPE_USIZE_PF "] (" MCM_DTYPE_USIZE_PF ") -", req_len2, count);
    for(idx = 0; idx < count; idx++)
    {
        DMSG("%d", req_data2[idx]);
    }

    if(mcm_lulib_run(&self_lulib, path1, &req_data2, req_len2, (void **) &rep_data2, &rep_len2)
                     < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

    count = rep_len2 / sizeof(int);
    DMSG("recv [" MCM_DTYPE_USIZE_PF "] (" MCM_DTYPE_USIZE_PF ") -", rep_len2, count);
    for(idx = 0; idx < count; idx++)
    {
        DMSG("%d", rep_data2[idx]);
    }
    free(rep_data2);

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}
</pre>
<br>
<pre class="css_pre_code">
內部模組部分

#include &lt;time.h&gt;
#include &lt;errno.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_user_data_test_01(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len;
    char *tmp_buf;

    DMSG("string data test :");

    srand(time(NULL));

    // 外部程式傳來的資料.

    DMSG("recv [" MCM_DTYPE_USIZE_PF "][%s]",
         this_session->req_data_len, (char *) this_session->req_data_con);

    // 內部模組要回傳的資料.

    tmp_len = 256;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "internal data %u", rand());
    tmp_len = strlen(tmp_buf) + 1;
    DMSG("send [" MCM_DTYPE_USIZE_PF "][%s]", tmp_len, tmp_buf);

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

int mcm_module_user_data_test_02(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len, idx, count;
    int *tmp_buf;

    DMSG("bytes data test :");

    srand(time(NULL));

    // 外部程式傳來的資料.

    tmp_buf = (int *) this_session->req_data_con;
    count = this_session->req_data_len / sizeof(int);
    DMSG("recv [" MCM_DTYPE_USIZE_PF "] (" MCM_DTYPE_USIZE_PF ") -",
         this_session->req_data_len, count);
    for(idx = 0; idx < count; idx++)
    {
        DMSG("%d", tmp_buf[idx]);
    }

    // 內部模組要回傳的資料.

    count = 6;
    tmp_buf = calloc(count, sizeof(int));
    if(tmp_buf == NULL)
    {
        DMSG("call calloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }
    tmp_len = sizeof(int) * count;

    for(idx = 0; idx < count; idx++)
        tmp_buf[idx] = rand() % 10;

    DMSG("send [" MCM_DTYPE_USIZE_PF "] (" MCM_DTYPE_USIZE_PF ") -", tmp_len, count);
    for(idx = 0; idx < count; idx++)
    {
        DMSG("%d", tmp_buf[idx]);
    }

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;

FREE_01:
    return fret;
}
</pre>
<br><br>

  </div>
</div>
<br>

<div class="css_div_box_frame_full">
  <div class="css_div_box_title">範例程式的使用</div>
  <div class="css_div_box_content">
    <br>

    <table class="css_table_list1">
      <tr>
        <td class="css_td_list1_l">01.&nbsp;</td>
        <td class="css_td_list1_r">
          範例程式目錄在 <font class="css_font_b1">mint_cm/usage/example/0502</font>.
        </td>
      </tr>
    </table>
    <br><br>

    <table class="css_table_list1">
      <tr>
        <td class="css_td_list1_l">02.&nbsp;</td>
        <td class="css_td_list1_r">
          下面關於 <font class="css_font_p1">make</font> 的操作沒有特別註明的話都是在
          <font class="css_font_b1">mint_cm</font> 目錄.
        </td>
      </tr>
    </table>
    <br><br>

    <table class="css_table_list1">
      <tr>
        <td class="css_td_list1_l">03.&nbsp;</td>
        <td class="css_td_list1_r">
          第一次使用, 使用 <font class="css_font_p1">make example_add KEY=0502</font>
          載入範例並編譯.
        </td>
      </tr>
    </table>
    <br><br>

    <table class="css_table_list1">
      <tr>
        <td class="css_td_list1_l">04.&nbsp;</td>
        <td class="css_td_list1_r">
          <font class="css_font_b1">user_app/user_app_0502</font> 是範例程式,<br>
          必須先在目錄內使用 <font class="css_font_p1">make all</font> 進行編譯.<br><br>
          執行 <font class="css_font_b1">user_app_0502</font> 不需要參數就可測試.
        </td>
      </tr>
    </table>
    <br><br>

    <table class="css_table_list1">
      <tr>
        <td class="css_td_list1_l">05.&nbsp;</td>
        <td class="css_td_list1_r">
          先執行 mcm_daemon, 才可以使用 user_app_0502 做測試.
        </td>
      </tr>
    </table>
    <br><br>

    <table class="css_table_list1">
      <tr>
        <td class="css_td_list1_l">06.&nbsp;</td>
        <td class="css_td_list1_r">
          測試完畢不使用後, 使用 <font class="css_font_p1">make example_del KEY=0502</font>
          將範例移除.
        </td>
      </tr>
    </table>
    <br><br>

    <table class="css_table_list1">
      <tr>
        <td class="css_td_list1_l">07.&nbsp;</td>
        <td class="css_td_list1_r">
          範例程式目錄下的檔案在做完 <font class="css_font_p1">make example_add</font>
          後會複製到真正使用的位置, 要修改做測試的話要改在複製後的.<br>
          <table class="css_table_list2">
            <tr>
              <td class="css_td_list2_r1">
                來源 <font class="css_font_b1">profile/mcm_data_profile_0502.xml</font><br>
                目地 <font class="css_font_b1">mint_cm/mcm_build/mcm_data_profile.xml</font><br>
                資料模型範例<br>
                有修改要使用 <font class="css_font_p1">make all</font> 重新編譯
              </td>
            </tr>
            <tr>
              <td class="css_td_list2_r1">
                來源 <font class="css_font_b1">profile/mcm_store_profile_default_0502.txt</font><br>
                目地 <font class="css_font_b1">mint_cm/mcm_build/mcm_store_profile_default.txt</font><br>
                資料預設值範例<br>
                使用 <font class="css_font_p1">make all</font> 後會再複製到 <font class="css_font_b1">mint_cm/run</font>
              </td>
            </tr>
            <tr>
              <td class="css_td_list2_r1">
                來源 <font class="css_font_b1">module/mcm_module_0502.c</font><br>
                目地 <font class="css_font_b1">mint_cm/mcm_daemon/mcm_module</font><br>
                內部模組範例<br>
                有修改要使用 <font class="css_font_p1">make all</font> 重新編譯
              </td>
            </tr>
          </table>
        </td>
      </tr>
    </table>
    <br>

  </div>
</div>
<br>

</body>

</html>
